package 抽象语法树遍历器;

import 抽象语法树类.*;
import 抽象语法树类.函数定义;
import 抽象语法树类.字面量类.*;
import 抽象语法树类.抽象语法树;
import 抽象语法树类.表达式类.*;
import 抽象语法树类.表达式类.二元表达式类.*;
import 抽象语法树类.语句类.*;

public class 抽象语法树访问器<T> {

    public T 访问(抽象语法树 抽象语法树) {
        if (抽象语法树 instanceof 代码块 代码块) {
            return 访问代码块(代码块);
        } else if (抽象语法树 instanceof 函数定义 函数定义) {
            return 访问函数定义(函数定义);
        } else if (抽象语法树 instanceof 变量定义 变量定义) {
            return 访问变量定义(变量定义);
        } else if (抽象语法树 instanceof 程序节点 程序节点) {
            return 访问程序节点(程序节点);
        } else if (抽象语法树 instanceof 符号引用 符号引用) {
            return 访问符号引用(符号引用);
        } else if (抽象语法树 instanceof 结构体定义 结构体定义) {
            return 访问结构体定义(结构体定义);
        } else if (抽象语法树 instanceof 语句 语句) {
            return 访问语句(语句);
        } else if (抽象语法树 instanceof 表达式 表达式) {
            return 访问表达式(表达式);
        } else if (抽象语法树 instanceof 字面量 字面量) {
            return 访问字面量(字面量);
        }
        
        throw new RuntimeException();
    }

    protected T 访问代码块(代码块 代码块) {
        T 结果 = null;
        for (var 语句 : 代码块.语句列表) {
            结果 = 访问(语句);
        }
        
        return 结果;
    }

    protected T 访问函数定义(函数定义 函数定义) {
        if (函数定义.参数 != null) {
            for (var 参数 : 函数定义.参数) {
                访问(参数);
            }
        }
        
        return 访问(函数定义.代码块);
    }

    protected T 访问变量定义(变量定义 变量定义) {
        return null;
    }

    protected T 访问程序节点(程序节点 程序节点) {
        if(程序节点.子节点 == null) return null;
        T 结果 = null;
        for (var 子节点 : 程序节点.子节点) {
            结果 = 访问(子节点);
        }
        
        return 结果;
    }

    protected T 访问符号引用(符号引用 符号引用) {
        return null;
    }

    protected T 访问结构体定义(结构体定义 结构体定义) {
        T 结果 = null;
        if (结构体定义.成员 != null) {
            for (var 成员 : 结构体定义.成员) {
                结果 = 访问(成员);
            }
        }
        
        return 结果;
    }


    // 语句类

    protected T 访问语句(语句 语句) {
       if (语句 instanceof If语句 If语句) {
            return 访问If语句(If语句);
        } else if (语句 instanceof While语句 While语句) {
            return 访问While语句(While语句);
        } else if (语句 instanceof 函数调用语句 函数调用语句) {
            return 访问函数调用语句(函数调用语句);
        } else if (语句 instanceof 打印语句 打印语句) {
            return 访问打印语句(打印语句);
        } else if (语句 instanceof 赋值语句 赋值语句) {
            return 访问赋值语句(赋值语句);
        } else if (语句 instanceof 返回语句 返回语句) {
            return 访问返回语句(返回语句);
        }
       
       throw new RuntimeException();
    }

    protected T 访问If语句(If语句 If语句) {
        访问(If语句.条件);
        访问(If语句.真块);
        if (If语句.假块 != null) {
            return 访问(If语句.假块);
        }
        return null;
    }

    protected T 访问While语句(While语句 While语句) {
        访问(While语句.条件);
        return 访问(While语句.代码块);
    }

    protected T 访问函数调用语句(函数调用语句 函数调用语句) {
        if (函数调用语句.参数 == null) {
            return null;
        }
        
        T 结果 = null;
        for (var 参数 : 函数调用语句.参数) {
            结果 = 访问(参数);
        }
        
        return 结果;
    }

    protected T 访问打印语句(打印语句 打印语句) {
        return 访问(打印语句.表达式);
    }

    protected T 访问赋值语句(赋值语句 赋值语句) {
        访问(赋值语句.右值);
        return 访问(赋值语句.左值);
    }

    protected T 访问返回语句(返回语句 返回语句) {
        return 访问(返回语句.返回值);
    }


    // 表达式类

    protected T 访问表达式(表达式 表达式) {
        if (表达式 instanceof 二元表达式 二元表达式) {
            return 访问二元表达式(二元表达式);
        } else if (表达式 instanceof 实例化表达式 实例化表达式) {
            return 访问实例化表达式(实例化表达式);
        } else if (表达式 instanceof 成员访问表达式 成员访问表达式) {
            return 访问成员访问表达式(成员访问表达式);
        }
        
        throw new RuntimeException();
    }

    protected T 访问实例化表达式(实例化表达式 实例化表达式) {
        return null;
    }

    protected T 访问成员访问表达式(成员访问表达式 成员访问表达式) {
        访问(成员访问表达式.对象);
        return 访问(成员访问表达式.成员);
    }

    // 二元表达式类

    protected T 访问二元表达式(二元表达式 二元表达式) {
        if (二元表达式 instanceof 小于表达式 小于表达式) {
            return 访问小于表达式(小于表达式);
        } else if (二元表达式 instanceof 加法表达式 加法表达式) {
            return 访问加法表达式(加法表达式);
        } else if (二元表达式 instanceof 判等表达式 判等表达式) {
            return 访问判等表达式(判等表达式);
        } else if (二元表达式 instanceof 减法表达式 减法表达式) {
            return 访问减法表达式(减法表达式);
        } else if (二元表达式 instanceof 乘法表达式 乘法表达式) {
            return 访问乘法表达式(乘法表达式);
        }
        
        throw new RuntimeException();
    }

    protected T 访问乘法表达式(乘法表达式 乘法表达式) {
        访问(乘法表达式.左值);
        return 访问(乘法表达式.右值);
    }

    protected T 访问减法表达式(减法表达式 减法表达式) {
        访问(减法表达式.左值);
        return 访问(减法表达式.右值);
    }

    protected T 访问判等表达式(判等表达式 判等表达式) {
        访问(判等表达式.左值);
        return 访问(判等表达式.右值);
    }

    protected T 访问加法表达式(加法表达式 加法表达式) {
        访问(加法表达式.左值);
        return 访问(加法表达式.右值);
    }

    protected T 访问小于表达式(小于表达式 小于表达式) {
        访问(小于表达式.左值);
        return 访问(小于表达式.右值);
    }


    // 字面量类

    protected T 访问字面量(字面量 字面量) {
        if (字面量 instanceof 浮点型字面量 浮点型字面量) {
            return 访问浮点型字面量(浮点型字面量);
        } else if (字面量 instanceof 文本型字面量 文本型字面量) {
            return 访问文本型字面量(文本型字面量);
        } else if (字面量 instanceof 整数型字面量 整数型字面量) {
            return 访问整数型字面量(整数型字面量);
        } else if (字面量 instanceof 字符型字面量 字符型字面量) {
            return 访问字符型字面量(字符型字面量);
        }
        
        throw new RuntimeException();
    }

    protected T 访问字符型字面量(字符型字面量 字符型字面量) {
        return null;
    }

    protected T 访问整数型字面量(整数型字面量 整数型字面量) {
        return null;
    }

    protected T 访问文本型字面量(文本型字面量 文本型字面量) {
        return null;
    }

    protected T 访问浮点型字面量(浮点型字面量 浮点型字面量) {
        return null;
    }
}
